<template>
  <div class="model-form">
    <el-page-header @back="goBack" content="更新">
    </el-page-header>
    <div class="model-content">
      <el-form ref="ruleForm" :rules="rules" :model="form" label-width="160px">
        <el-row :gutter="10">
          <el-col :span="22">
            <el-form-item label="模板代码" prop="id">
              <el-input v-model="form.id" name="id" disabled>
              </el-input>
            </el-form-item>

          </el-col>
          <el-col :span="22">
            <el-form-item label="模板名称" prop="name">
              <el-input v-model="form.name" name="name">
              </el-input>
            </el-form-item>
          </el-col>
          <el-col :span="22">
            <el-form-item label="功能分类" prop="name">
              <el-tree-select
                  v-model="form.queryCatalog"
                  :data="catalogOptions"
                  check-strictly
                  node-key="id"
                  :render-after-expand="false"
                  style="width: 240px"
              />
            </el-form-item>
          </el-col>
          <el-col :span="22">
            <el-form-item>
              <ParamTable :form="form"></ParamTable>
            </el-form-item>
          </el-col>
          <el-col :span="22">
            <el-form-item label="查询类型" prop="id">
              <el-radio-group v-model="form.queryType">
                <el-radio-button label="分页" :value="1"/>
                <el-radio-button label="列表" :value="2"/>
                <el-radio-button label="批量查询" :value="3"/>

              </el-radio-group>
            </el-form-item>

          </el-col>
          <el-col :span="22" v-if="form.queryType===1||form.queryType===2">
            <el-form-item label="后台java映射类" prop="content">
              <el-input v-model="form.className">
                <template #append>
                  <el-button @click="querySql">获取sql语句</el-button>
                </template>
              </el-input>

            </el-form-item>
          </el-col>
          <el-col :span="22" v-if="form.queryType===1||form.queryType===2">
            <el-form-item label="查询sql语句" prop="content">
              <div style="display: flex; align-items: center; margin-bottom: 10px;">
                <el-button type="primary" @click="showSqlGenerator">
                  <el-icon><ChatLineRound /></el-icon>
                  自然语言生成SQL
                </el-button>
              </div>
              <div class="code-editor-container" :class="{ 'fullscreen': isFullscreen }">
                <div class="code-editor-header">
                  <el-button v-if="!isFullscreen" type="text" @click="toggleCodeEditor">
                    {{ isCodeEditorExpanded ? '折叠' : '展开' }}
                    <el-icon><component :is="isCodeEditorExpanded ? 'ArrowUp' : 'ArrowDown'" /></el-icon>
                  </el-button>
                  <el-button type="text" @click="toggleFullscreen">
                    {{ isFullscreen ? '退出全屏' : '全屏' }}
                    <el-icon><component :is="isFullscreen ? 'Close' : 'FullScreen'" /></el-icon>
                  </el-button>
                </div>
                <div class="code-editor-content" :class="{ 'expanded': isCodeEditorExpanded }">
                  <scCodeEditor v-model="form.content" name="content" mode="sql" style="width: 100%;height: auto">
                  </scCodeEditor>
                </div>
              </div>
            </el-form-item>
          </el-col>
          <el-col :span="22" v-if="form.queryType===3">
            <el-form-item label="查询执行类型" prop="id">
              <el-radio-group v-model="form.sqlBatchObject.execType">
                <el-radio-button label="串行查询" :value="1"/>
                <el-radio-button label="并行查询" :value="2"/>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="22" v-if="form.queryType===3">
            <el-form-item label="批量查询" prop="content">
              <el-table :data="form.sqlBatchObject.sqlObjects" style="width: 100%;">
                <el-table-column label="查询名称" prop="label" width="160">
                  <template #default="scope">
                    <el-input v-model="scope.row.label"></el-input>
                  </template>
                </el-table-column>
                <el-table-column label="变量名称" prop="varName" width="160">
                  <template #default="scope">
                    <el-input v-model="scope.row.varName"></el-input>
                  </template>
                </el-table-column>
                <el-table-column label="查询类型" prop="varName" width="160">
                  <template #default="scope">
                    <el-select v-model="scope.row.queryType" clearable placeholder="显示区域">
                      <el-option label="分页" :value="1"/>
                      <el-option label="列表" :value="2"/>
                      <el-option label="统计" :value="3"/>
                      <el-option label="单对象" :value="4"/>
                      <el-option label="单值" :value="5"/>
                      <el-option label="执行sql" :value="6"/>
                    </el-select>
                  </template>
                </el-table-column>
                <el-table-column label="查询代码" prop="sql">
                  <template #default="scope">
                    <scCodeEditor v-model="scope.row.sql" name="content" mode="sql" style="width: 100%;height: auto">
                    </scCodeEditor>
                  </template>
                </el-table-column>
                <el-table-column width="80" align="center" fixed="right" label="操作">
                  <template #default="scope">
                    <el-button text class="operation_bt" type="danger" style="cursor: pointer;"
                               @click="deleteQuery(scope.$index)">删除
                    </el-button>
                  </template>
                </el-table-column>
              </el-table>
              <el-button @click="addQuery" style="margin-top: 15px;">添加查询</el-button>
            </el-form-item>
          </el-col>
          <el-col :span="22">
            <el-form-item label="模板类型" prop="type">
              <el-radio-group v-model="form.type">
                <el-radio :value="1">公共查询</el-radio>
                <el-radio :value="2">私有查询</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="22" v-if="form.type===2">
            <el-form-item label="权限标记" prop="permission">
              <el-input v-model="form.permission" name="permission"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="22">
            <el-form-item label="结果处理" prop="resultHandleType">
              <el-radio-group v-model="form.resultHandleType">
                <el-radio-button label="结果处理" :value="1"/>
                <el-radio-button label="结果不处理" :value="2"/>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="22" v-if="form.resultHandleType==1">
            <el-form-item label="结果处理并发方式" prop="resultHandleType" >
              <el-radio-group v-model="form.resultHandle.execType" @change="changeResultHandle">
                <el-radio-button label="串行查询" :value="1"/>
                <el-radio-button label="并行查询" :value="2"/>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="22" v-if="form.resultHandleType==1">
            <el-form-item label="结果处理配置"  >
              <sc-form-table v-model="form.resultHandle.resultHandleObjects" drag-sort :addTemplate="addTemplate">
                <el-table-column width="150" align="center" label="处理器">
                  <template #default="scope">
                  <el-select v-model="scope.row.handleType"  placeholder="选择类型"  >
                    <el-option label="数据库查询" value="resultDbHandle"/>
                    <el-option label="网络表单请求" value="httpFormHandle"/>
                    <el-option label="网络json请求" value="httpJsonHandle"/>
                  </el-select>
                  </template>

                </el-table-column>
                <el-table-column width="160" align="center" label="查询模型">
                  <template #default="scope">
                    <el-input v-model="scope.row.model"></el-input>
                  </template>
                </el-table-column>
                <el-table-column width="150" align="center" label="集合变量">
                  <template #default="scope">
                    <el-input v-model="scope.row.resultKey"></el-input>
                  </template>
                </el-table-column>
                <el-table-column width="120" align="center" label="结果类型">
                  <template #default="scope">
                    <el-select v-model="scope.row.resultType"  placeholder="选择类型"  >
                      <el-option label="单对象" value="single"/>
                      <el-option label="集合" value="list"/>
                    </el-select>
                  </template>

                </el-table-column>
                <el-table-column align="center" label="请求参数">
                  <template #default="scope">
                    <sc-form-table v-model="scope.row.params" drag-sort :addTemplate="addParamTemplate">
                      <el-table-column width="150" align="center" label="参数来源">
                        <template #default="scope">
                          <el-select v-model="scope.row.type"  placeholder="参数来源"  >
                            <el-option label="请求" value="filter"/>
                            <el-option label="查询结果" value="result"/>
                          </el-select>
                        </template>
                      </el-table-column>
                      <el-table-column width="150" align="center" label="参数变量">
                        <template #default="scope">
                          <el-input v-model="scope.row.param"></el-input>
                        </template>

                      </el-table-column>
                      <el-table-column width="150" align="center" label="请求变量">
                        <template #default="scope">
                          <el-input v-model="scope.row.requestKey"></el-input>
                        </template>
                      </el-table-column>
                    </sc-form-table>
                  </template>

                </el-table-column>
              </sc-form-table>
            </el-form-item>
          </el-col>
          <el-col :span="22">
            <el-form-item label="模板描述" prop="note">
              <el-input v-model="form.note" name="note" type="textarea"></el-input>
            </el-form-item>

          </el-col>


          <el-col :span="22">
            <el-form-item>
              <el-button @click="goBack">取消</el-button>
              <el-button type="primary" @click="updateData">确定</el-button>
              <el-button type="primary" @click="updateStaging">暂存</el-button>
              <el-button type="primary" @click="saveData">保存测试</el-button>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </div>
    <el-dialog
        v-model="dialogVisible"
        title="发送请求示例"
        width="800"
    >
      <el-form :model="form1" label-width="auto">
        <el-form-item label="测试账套">
          <el-select v-model="form1.tenant">
            <el-option v-for="(item,index) of tenantList" :key="index" :value="item.id"  :label="item.name"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="网址">
          <el-select  v-model="form1.url">
            <el-option label="列表" value="/data/list"></el-option>
            <el-option label="分页" value="/data/search"></el-option>
            <el-option label="单对象" value="/data/selectOne"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="json">
          <el-input type="textarea" :rows="5" v-model="form1.json" autocomplete="off" />
        </el-form-item>
        <el-form-item class="json-send">
          <el-button type="primary" @click="sendTest">发送</el-button>
          <el-button type="info" @click="resetTest">重置</el-button>
        </el-form-item>
        <el-form-item>
          <el-input type="textarea" v-if="isShowResult"  :rows="10" readonly class="result"   v-model="result"></el-input>
        </el-form-item>
      </el-form>
    </el-dialog>

    <!-- SQL生成器组件 -->
    <SqlGenerator
      v-model="sqlGeneratorVisible"
      @generated="handleSqlGenerated"
    />




    <div class="floating-buttons">
      <el-button type="primary" @click="updateData" class="floating-button">
        <el-icon><Check /></el-icon>
        确定
      </el-button>
      <el-button type="primary" @click="updateStaging" class="floating-button">
        <el-icon><Document /></el-icon>
        暂存
      </el-button>
      <el-button type="primary" @click="saveData" class="floating-button">
        <el-icon><Search /></el-icon>
        查询测试
      </el-button>
      <el-button type="primary" @click="showCodeEditor" class="floating-button" v-if="form.queryType===1||form.queryType===2">
        <el-icon><Document /></el-icon>
        查看代码
      </el-button>
      <el-button type="primary" @click="showParamConfig" class="floating-button">
        <el-icon><Setting /></el-icon>
        参数配置
      </el-button>
      <el-button type="primary" @click="showSqlKeywords" class="floating-button" v-if="form.queryType===1||form.queryType===2">
        <el-icon><Key /></el-icon>
        SQL关键字
      </el-button>
      <el-button type="primary" @click="showSnippets" class="floating-button" v-if="form.queryType===1||form.queryType===2">
        <el-icon><Collection /></el-icon>
        代码段
      </el-button>
      <el-button type="primary" @click="showAiAssistant" class="floating-button">
        <el-icon><ChatDotRound /></el-icon>
        AI辅助
      </el-button>
      <el-button
          v-show="showBackToTop"
          type="primary"
          @click="scrollToTop"
          class="floating-button back-to-top"
      >
        <el-icon><Top /></el-icon>
        置顶
      </el-button>
    </div>

    <el-dialog
        v-model="paramConfigVisible"
        title="参数配置"
        width="90%"
        :fullscreen="true"
        :close-on-click-modal="false"
    >
      <div class="param-config-container">
        <ParamTable :form="form" />
      </div>
    </el-dialog>

    <SqlSnippets ref="sqlSnippetsRef" @use="handleSnippetUse" />
    <SqlKeywords ref="sqlKeywordsRef" @use="handleKeywordUse" />
    <AiAssistant
        ref="aiAssistantRef"
        :sql="form.content"
        :query-type="form.queryType"
        :params="form.extData?.filters || []"
        @update:sql="handleSqlUpdate"
        :on-save-snippet="handleSaveSnippet"
    />

  </div>

</template>

<script setup>
import {defineAsyncComponent, ref, onMounted} from "vue";
import {useUpdate} from "@/uses/useUpdate";
import http from "@/utils/request";
import ParamTable from "@/components/ParamTable.vue";
import scFormTable from "@/components/scFormTable/index.vue";
import SqlGenerator from '@/components/SqlGenerator/index.vue';
import {ChatLineRound, Check, Document} from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import {useData} from "@/utils/useData.js";
import SqlSnippets from "@/views/pages/queryTemplate/components/SqlSnippets.vue";
import SqlKeywords from "@/views/pages/queryTemplate/components/SqlKeywords.vue";
import AiAssistant from "@/views/pages/queryTemplate/components/AiAssistant.vue";

const scCodeEditor = defineAsyncComponent(() => import('@/components/scCodeEditor/index.vue'));

const{listData:catalogOptions}= useData("/queryCatalog/list",{fetch:1,depth:1})

const sqlSnippetsRef = ref(null)
const sqlKeywordsRef = ref(null)
const aiAssistantRef = ref(null)
const paramConfigVisible = ref(false)
const isCodeEditorExpanded = ref(true)
const isFullscreen = ref(false)

const dialogVisible = ref(false)
const sqlGeneratorVisible = ref(false)
const result = ref({})
const addTemplate = ref({
  fieldName: null,
  javaName: null,
  fieldType: null
})
const addParamTemplate = ref({
  fieldName: null,
  javaName: null,
  fieldType: null
})
const isShowResult = ref(false)

const form = ref({
  id: '',
  name: '',
  content: '',
  type: '',
  note: '',
  className: null,
  queryType: null,
  permission: null,
  extData: {
    filters: [],
    fields: [],
    params: [],
    sortNames: []
  }
})
const form1 = ref({
  url: '/data/list',
  json: '',
  tenant: ''
})


const rules = ref({
  id: [
    {required: true, message: '请输入模板代码', trigger: 'blur'}
  ],
  name: [
    {required: true, message: '请输入模板名称', trigger: 'blur'}
  ],
})

const ruleForm = ref(null);
const tenantList = ref([]);
onMounted(() => {
  getTenantList()
})
const getTenantList = async() => {
  let res = await http.post('/tenant/list',{});
  if (res.code === 200) {
    tenantList.value = res.data
    form1.value.tenant = tenantList.value[0].id
  }
}
const addQuery = () => {
  if (!form.value.sqlBatchObject) {
    form.value.sqlBatchObject = {};
  }
  if (!form.value.sqlBatchObject.sqlObjects) {
    form.value.sqlBatchObject.sqlObjects = [];
  }
  form.value.sqlBatchObject.sqlObjects.push({
    label: "",
    sql: "",
    queryType: "",
    varName: ""
  })

}
const deleteQuery = (row) => {
  form.value.sqlBatchObject.sqlObjects.splice(row, 1);
}

const {updateData, goBack,updateStaging} = useUpdate("queryTemplate", form, ruleForm, () => {
  if (!form.value.extData) {
    form.value.extData = {};
  }
  if (!form.value.extData.filters) {
    form.value.extData.filters = [];
  }
  if (!form.value.sqlBatchObject) {
    form.value.sqlBatchObject = {};
  }
  if (!form.value.resultHandle) {
    form.value.resultHandle = {};
  }
  if (!form.value.resultHandle.resultHandleObjects) {
    form.value.resultHandle.resultHandleObjects = [];
  }

  const obj = {}
  form.value.extData.filters.forEach((item) => {
    obj[item.javaName] = null;
  })
  form1.value.json = JSON.stringify({
    model: form.value.id,
    filters: obj
  },null,2)
})

const querySql = async () => {
  let res = await http.post('/query/getQuery', {
    className: form.value.className,
    alias: "model"
  })

  if (res.code === 200) {
    form.value.content = res.data;
  }
}

const changeResultHandle=()=>{

  console.info("changeResultHandle")
  if (form.value.resultHandleType===1){
    if (!form.value.resultHandle){
      form.value.resultHandle={};
    }
    if (!form.value.resultHandle.resultHandleObjects){
      form.value.resultHandle.resultHandleObjects=[];
    }
  }

}
const saveData = () => {
  updateStaging();
  dialogVisible.value=true
}
const getConfig = () =>{
  let config = {};
  let headers = {};
  headers.tenant = form1.value.tenant;
  config.headers = headers;
  return config;
}
const sendTest = async() => {
  let config = getConfig();
  console.info(config)
  const res = await http.post(form1.value.url, JSON.parse(form1.value.json), config)
  //result.value = JSON.stringify(res).replaceAll(/,/g, ',\n');
  result.value = JSON.stringify(res, null, 2);
  isShowResult.value = true
}
const resetTest = () =>{
  result.value = '';
  isShowResult.value = false
}

// 显示SQL生成器
const showSqlGenerator = () => {
  sqlGeneratorVisible.value = true
}

// 处理生成的SQL
const handleSqlGenerated = (sql) => {
  form.value.content = sql
  ElMessage.success('已应用生成的SQL')
}

const showSqlKeywords = () => {
  sqlKeywordsRef.value?.show()
}
const showSnippets = () => {
  sqlSnippetsRef.value?.show()
}
const handleSnippetUse = (code) => {
  if (form.value.content) {
    form.value.content += '\n\n' + code
  } else {
    form.value.content = code
  }
}
const handleKeywordUse = (keyword) => {
  if (form.value.content) {
    form.value.content += ' ' + keyword + ' '
  } else {
    form.value.content = keyword + ' '
  }
}
const showAiAssistant = () => {
  aiAssistantRef.value?.show()
}
const handleSqlUpdate = (sql) => {
  form.value.content = sql
}
const handleSaveSnippet = (code) => {
  sqlSnippetsRef.value?.addSnippet(code)
}
const toggleCodeEditor = () => {
  isCodeEditorExpanded.value = !isCodeEditorExpanded.value
}
const toggleFullscreen = () => {
  isFullscreen.value = !isFullscreen.value
}
const showCodeEditor = () => {
  isFullscreen.value = true
  isCodeEditorExpanded.value = true
}
const showParamConfig = () => {
  paramConfigVisible.value = true
}
</script>

<style scoped>
.json-send ::v-deep .el-form-item__content{
  justify-content: flex-end;
}
.result{
  width:96%;
  color:#fff;
  padding:10px;
  border-radius: 5px;
  line-height: 20px;
  margin-right:16px;
}


.code-editor-container {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  width: 100%;
  position: relative;
  transition: all 0.3s ease;
}

.code-editor-container.fullscreen {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2000;
  margin: 0;
  border-radius: 0;
  background: #fff;
}

.code-editor-header {
  padding: 8px;
  border-bottom: 1px solid #dcdfe6;
  background-color: #f5f7fa;
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.code-editor-content {
  overflow: visible;
  transition: all 0.3s ease;
  display: block;
}

.code-editor-content:not(.expanded) {
  display: none;
}

.code-editor-container.fullscreen .code-editor-content {
  display: block;
  height: calc(100vh - 50px) !important;
  overflow-y: auto;
  overflow-x: hidden;
}

.code-editor-container.fullscreen .code-editor-content :deep(.sc-code-editor) {
  height: auto !important;
  width: 100% !important;
}

.code-editor-container.fullscreen .code-editor-content :deep(.sc-code-editor .CodeMirror) {
  height: auto !important;
  width: 100% !important;
}

.code-editor-container.fullscreen .code-editor-content :deep(.CodeMirror-scroll) {
  overflow-y: auto !important;
  overflow-x: hidden !important;
  height: auto !important;
}

.code-editor-container.fullscreen .code-editor-content :deep(.CodeMirror-lines) {
  padding: 10px 0 !important;
}


.floating-buttons {
  position: fixed;
  right: 20px;
  bottom: 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  z-index: 100;
  align-items: center;
}

.floating-button {
  padding: 12px 20px;
  border-radius: 50px;
  box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
  transition: all 0.3s ease;
  width: 120px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  box-sizing: border-box;
}

.floating-button .el-icon {
  margin-right: 0;
}

.floating-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px 0 rgba(0,0,0,0.2);
}
</style>
